#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <wait.h>
#include <stdlib.h>

extern char** environ;
// 函数指针类型
typedef void (*func_t)();

#define NUM 5
//函数指针数组
func_t handlers[NUM+1];

// 如下是任务
void DownLoad()
{
    printf("我是一个下载的任务...\n");
}
void Flush()
{
    printf("我是一个刷新的任务...\n");
}
void Log()
{
    printf("我是一个记录日志的任务...\n");
}

// 注册
void registerHandler(func_t h[], func_t f)
{
    int i = 0;
    for(; i < NUM; i++)
    {
        if(h[i] == NULL)break;
    }
    //往数组里面添加函数指针
    if(i == NUM) return;
    h[i] = f;
    h[i+1] = NULL;
}

int main()
{ 
////进程的非阻塞调用演示   

  registerHandler(handlers, DownLoad);
  registerHandler(handlers, Flush);
  registerHandler(handlers, Log);
  pid_t id = fork();
  //如果是自子进程一直在做工作
  if(id == 0)
  {
      //child
     // while(1)        //子进程不退出，父进程永远不退出
      int cnt = 3;
      while(1)
      {
          sleep(1);
          printf("child pid: %d, parent pid: %d\n", getpid(), getppid());
      }
     exit(1);
  }
  
  //father
  while(1)
  {
      int status;
      pid_t wid = waitpid(id,&status,WNOHANG);
      if(wid > 0)
      {
          printf("wait success! wid:%d, exit_code:%d\n",wid, (status>>8));
          break;
      }
      else if(wid == 0)
      {     
          sleep(1);
         // printf("正在等待当前子进程\n");
         // printf("本轮调用结束\n");
          int i = 0;
          for(; handlers[i]; i++)
          {
              handlers[i]();        //调用函数指针数组需要使用括号
          }
      }
      else 
      {
          printf("wait failed!\n");
          break;
      }
  }









////////////////////////进程等待演示
   // pid_t id = fork();
   // //如果是自子进程一直在做工作
   // if(id == 0)
   // {
   //     //child
   //    // while(1)        //子进程不退出，父进程永远不退出
   //     int cnt = 3;
   //     while(1)
   //     {
   //         sleep(1);
   //         printf("child process!\n");
   //         int *p=0;
   //         *p=100;
   //         int a=10;
   //         a/=0;
   //     }
   //    exit(1);
   // }

    ////father
    //int status = 0;
    //sleep(5);
    //pid_t rid = waitpid(id, &status, 0);
    //if(rid > 0)     //进程正常退出
    //{
    //    if(WIFEXITED(status))
    //    {
    //        printf("wait success\n");
    //        //printf("pid: %d\nstatus: %d\n",getpid(),(status>>8)&0xff);
    //        printf("pid: %d\nstatus: %d\n",getpid(),WEXITSTATUS(status));

    //    }
    //    else 
    //    {
    //        printf("子进程退出异常！\n");
    //    }
    //}
    //else if(rid < 0)        // 进程异常退出
    //{
    //    printf("wait failed\n %d",WEXITSTATUS(status));
    //    exit(0);
    //}
    //else 
    //{
    //    printf("other!\n");
    //}

    return 0;
}



//////环境变量演示
   // if(putenv("chen=peng")!=0)
   //     printf("导入环境环境变量失败\n");
   // else 
   // {
   //     printf("%s\n",getenv("chen"));
   // }

   // char** e = environ;
   // while(*e != NULL)
   // {
   //     *e++;
   //      printf("%s\n",*e);
   // }
